using MediatR;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using SumerCoreDevOps.Application.SystemConfigs.Commands;
using SumerCoreDevOps.Application.SystemConfigs.Queries;
using SumerCoreDevOps.Domain.Entities;
using SumerCoreDevOps.Application.Dtos.Requests.SystemConfigs;
namespace SumerCoreDevOps.ControlApi.Controllers;

/// <summary>
/// 系统配置管理 API
/// </summary>
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class SystemConfigController : ControllerBase
{
    private readonly IMediator _mediator;
    private readonly ILogger<SystemConfigController> _logger;

    public SystemConfigController(IMediator mediator, ILogger<SystemConfigController> logger)
    {
        _mediator = mediator;
        _logger = logger;
    }

    /// <summary>
    /// 获取所有配置
    /// </summary>
    /// <returns>返回系统中所有配置项的列表,每个配置包含配置键、配置值、配置类型、分类、描述、是否需要重启等信息;如果发生错误则返回500状态码和错误详情</returns>
    [HttpGet]
    public async Task<ActionResult<List<SystemConfig>>> GetAllConfigs()
    {
        try
        {
            var configs = await _mediator.Send(new GetAllConfigsQuery());
            return Ok(configs);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取所有配置失败");
            return StatusCode(500, new { message = "获取配置失败", error = ex.Message });
        }
    }

    /// <summary>
    /// 获取指定配置
    /// </summary>
    /// <param name="configKey">配置键名</param>
    /// <returns>返回指定配置键的完整配置对象,包含配置键、配置值、配置类型、分类、描述等信息;如果配置不存在则返回404状态码和提示信息;发生错误时返回500状态码和错误详情</returns>
    [HttpGet("{configKey}")]
    public async Task<ActionResult<SystemConfig>> GetConfigByKey(string configKey)
    {
        try
        {
            var config = await _mediator.Send(new GetConfigQuery(configKey));
            if (config == null)
            {
                return NotFound(new { message = "配置不存在" });
            }

            return Ok(config);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取配置失败: {ConfigKey}", configKey);
            return StatusCode(500, new { message = "获取配置失败", error = ex.Message });
        }
    }

    /// <summary>
    /// 获取配置值
    /// </summary>
    /// <param name="configKey">配置键名</param>
    /// <param name="defaultValue">默认值（可选）</param>
    /// <returns>返回包含配置键和配置值的对象;如果配置不存在且提供了默认值则返回默认值,否则返回404状态码;发生错误时返回500状态码和错误详情</returns>
    [HttpGet("{configKey}/value")]
    public async Task<ActionResult<string>> GetConfigValue(string configKey, [FromQuery] string? defaultValue = null)
    {
        try
        {
            var value = await _mediator.Send(new GetConfigValueQuery(configKey, defaultValue));
            if (value == null)
            {
                return NotFound(new { message = "配置不存在" });
            }

            return Ok(new { configKey, value });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取配置值失败: {ConfigKey}", configKey);
            return StatusCode(500, new { message = "获取配置值失败", error = ex.Message });
        }
    }

    /// <summary>
    /// 按分类获取配置
    /// </summary>
    /// <param name="category">配置分类名称</param>
    /// <returns>返回指定分类下的所有配置列表,每个配置包含配置键、配置值、配置类型、描述等信息;如果该分类下没有配置则返回空列表;发生错误时返回500状态码和错误详情</returns>
    [HttpGet("category/{category}")]
    public async Task<ActionResult<List<SystemConfig>>> GetConfigsByCategory(string category)
    {
        try
        {
            var configs = await _mediator.Send(new GetConfigsByCategoryQuery(category));
            return Ok(configs);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "按分类获取配置失败: {Category}", category);
            return StatusCode(500, new { message = "获取配置失败", error = ex.Message });
        }
    }

    /// <summary>
    /// 更新配置
    /// </summary>
    /// <param name="configKey">配置键名</param>
    /// <param name="request">更新配置请求对象</param>
    /// <returns>返回200状态码、成功提示信息和requiresRestart布尔值(指示该配置是否需要重启服务才能生效);如果需要重启还会包含警告信息;如果配置不存在或无效则返回400状态码;发生错误时返回500状态码和错误详情</returns>
    [HttpPut("{configKey}")]
    public async Task<ActionResult<object>> UpdateConfig(
        string configKey,
        [FromBody] UpdateConfigRequest request)
    {
        try
        {
            var requiresRestart = await _mediator.Send(new UpdateConfigCommand(
                configKey,
                request.ConfigValue,
                request.UpdatedBy
            ));

            return Ok(new
            {
                message = "配置更新成功",
                requiresRestart,
                warning = requiresRestart ? "此配置需要重启服务才能生效" : null
            });
        }
        catch (InvalidOperationException ex)
        {
            return BadRequest(new { message = ex.Message });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "更新配置失败: {ConfigKey}", configKey);
            return StatusCode(500, new { message = "更新配置失败", error = ex.Message });
        }
    }

    /// <summary>
    /// 批量更新配置
    /// </summary>
    /// <param name="request">批量更新配置请求对象</param>
    /// <returns>返回200状态码、成功提示信息、各配置的更新结果字典(配置键到requiresRestart的映射)和总体requiresRestart布尔值;如果任一配置需要重启则总体requiresRestart为true并包含警告信息;如果配置无效则返回400状态码;发生错误时返回500状态码和错误详情</returns>
    [HttpPut("batch")]
    public async Task<ActionResult<object>> UpdateConfigs([FromBody] UpdateConfigsRequest request)
    {
        try
        {
            var results = await _mediator.Send(new UpdateConfigsCommand(
                request.Configs,
                request.UpdatedBy
            ));

            var anyRequiresRestart = results.Values.Any(r => r);

            return Ok(new
            {
                message = "配置批量更新成功",
                results,
                requiresRestart = anyRequiresRestart,
                warning = anyRequiresRestart ? "部分配置需要重启服务才能生效" : null
            });
        }
        catch (InvalidOperationException ex)
        {
            return BadRequest(new { message = ex.Message });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "批量更新配置失败");
            return StatusCode(500, new { message = "批量更新配置失败", error = ex.Message });
        }
    }

    /// <summary>
    /// 创建自定义配置
    /// </summary>
    /// <param name="request">创建配置请求对象</param>
    /// <returns>返回201状态码和新创建的配置完整对象,包括配置键、配置值、配置类型、分类、描述、是否需要重启、是否敏感、创建时间等字段;如果配置键已存在则返回400状态码和错误提示;发生错误时返回500状态码和错误详情</returns>
    [HttpPost]
    public async Task<ActionResult<SystemConfig>> CreateConfig([FromBody] CreateConfigRequest request)
    {
        try
        {
            var config = await _mediator.Send(new CreateConfigCommand(
                request.ConfigKey,
                request.ConfigValue,
                request.ConfigType ?? "String",
                request.Category,
                request.Description,
                request.RequiresRestart,
                request.IsSensitive,
                request.CreatedBy
            ));

            return CreatedAtAction(nameof(GetConfigByKey), new { configKey = config.ConfigKey }, config);
        }
        catch (InvalidOperationException ex)
        {
            return BadRequest(new { message = ex.Message });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "创建配置失败: {ConfigKey}", request.ConfigKey);
            return StatusCode(500, new { message = "创建配置失败", error = ex.Message });
        }
    }

    /// <summary>
    /// 删除配置
    /// </summary>
    /// <param name="configKey">配置键名</param>
    /// <returns>返回200状态码和成功提示信息;如果配置是系统必需配置不能删除则返回400状态码和错误提示;如果配置不存在则返回404状态码;发生错误时返回500状态码和错误详情</returns>
    [HttpDelete("{configKey}")]
    public async Task<ActionResult> DeleteConfig(string configKey)
    {
        try
        {
            await _mediator.Send(new DeleteConfigCommand(configKey));
            return Ok(new { message = "配置删除成功" });
        }
        catch (InvalidOperationException ex)
        {
            return BadRequest(new { message = ex.Message });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "删除配置失败: {ConfigKey}", configKey);
            return StatusCode(500, new { message = "删除配置失败", error = ex.Message });
        }
    }

    /// <summary>
    /// 获取网络配置（端口信息）
    /// </summary>
    /// <returns>返回网络相关配置的对象,包括controlApiPort(控制API端口)、tcpServerPort(TCP服务器端口)、nodeDefaultPort(节点默认端口)以及所有网络分类下的配置列表;发生错误时返回500状态码和错误详情</returns>
    [HttpGet("network")]
    public async Task<ActionResult<object>> GetNetworkConfig()
    {
        try
        {
            var configs = await _mediator.Send(new GetConfigsByCategoryQuery("Network"));

            return Ok(new
            {
                controlApiPort = configs.FirstOrDefault(c => c.ConfigKey == "ControlApiPort")?.ConfigValue,
                tcpServerPort = configs.FirstOrDefault(c => c.ConfigKey == "TcpServerPort")?.ConfigValue,
                nodeDefaultPort = configs.FirstOrDefault(c => c.ConfigKey == "NodeDefaultPort")?.ConfigValue,
                allConfigs = configs
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取网络配置失败");
            return StatusCode(500, new { message = "获取网络配置失败", error = ex.Message });
        }
    }

    /// <summary>
    /// 更新网络配置（端口信息）
    /// </summary>
    /// <param name="request">更新网络配置请求对象</param>
    /// <returns>返回200状态码、成功提示信息、各端口配置的更新结果字典和总体requiresRestart布尔值;端口配置变更通常需要重启服务才能生效,会包含警告信息;如果没有提供任何配置更新则返回400状态码;发生错误时返回500状态码和错误详情</returns>
    [HttpPut("network")]
    public async Task<ActionResult<object>> UpdateNetworkConfig([FromBody] UpdateNetworkConfigRequest request)
    {
        try
        {
            var configs = new Dictionary<string, string>();

            if (request.ControlApiPort.HasValue)
            {
                configs["ControlApiPort"] = request.ControlApiPort.Value.ToString();
            }

            if (request.TcpServerPort.HasValue)
            {
                configs["TcpServerPort"] = request.TcpServerPort.Value.ToString();
            }

            if (request.NodeDefaultPort.HasValue)
            {
                configs["NodeDefaultPort"] = request.NodeDefaultPort.Value.ToString();
            }

            if (!configs.Any())
            {
                return BadRequest(new { message = "没有提供任何配置更新" });
            }

            var results = await _mediator.Send(new UpdateConfigsCommand(configs, request.UpdatedBy));

            var anyRequiresRestart = results.Values.Any(r => r);

            return Ok(new
            {
                message = "网络配置更新成功",
                results,
                requiresRestart = anyRequiresRestart,
                warning = anyRequiresRestart ? "端口配置已更新，需要重启服务才能生效" : null
            });
        }
        catch (InvalidOperationException ex)
        {
            return BadRequest(new { message = ex.Message });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "更新网络配置失败");
            return StatusCode(500, new { message = "更新网络配置失败", error = ex.Message });
        }
    }
}
